package top.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import top.api.Constants.SystemConstants;
import top.api.domain.dto.AddArticleDto;
import top.api.domain.dto.UpdateArticleDto;
import top.api.domain.entity.Article;
import top.api.domain.entity.ArticleTag;
import top.api.domain.entity.Category;
import top.api.domain.vo.*;
import top.api.mapper.CategoryMapper;
import top.api.service.ArticleService;
import top.api.mapper.ArticleMapper;
import org.springframework.stereotype.Service;
import top.api.service.ArticleTagService;
import top.api.utils.BeanCopyUtils;
import top.api.utils.RedisCache;
import top.api.common.ResponseResult;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author 27465
* @description 针对表【sg_article(文章表)】的数据库操作Service实现
* @createDate 2023-01-28 19:35:57
*/
@Service
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService{

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ArticleTagService articleTagService;

    @Override
    public ResponseResult hotArticleList() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        // 查询正式文章 0: 已发布  1: 草稿
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        // 按照浏览量 降序 排序
        queryWrapper.orderByDesc(Article::getViewCount);

        // 只查询前 10 条数据
        Page<Article> pageInfo = new Page<>(1,10);

        articleMapper.selectPage(pageInfo,queryWrapper);

        List<Article> articleList = pageInfo.getRecords();

        // 进行vo分装
        List<HotArticleVo> vos = BeanCopyUtils.copyBeanList(articleList, HotArticleVo.class);

        return ResponseResult.okResult(vos);
    }

    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        Page<ArticleListVo> page = new Page<>(pageNum,pageSize);

        List<ArticleListVo> articleListVos = articleMapper.articleListPage(page, categoryId);
        // 拷贝到PageVo对象
        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getArticleDetail(Long id) {
        // 根据id查询文章数据
        Article article = articleMapper.selectById(id);
        // 根据categoryId查询分类列表数据
        Long categoryId = article.getCategoryId();

        Category category = categoryMapper.selectById(categoryId);
        // 数据拷贝
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        if (Objects.nonNull(category)){
            articleDetailVo.setCategoryName(category.getName());
        }
        return ResponseResult.okResult(articleDetailVo);
    }

    @Override
    public ResponseResult updateViewCount(Long id) {
        redisCache.incrementCacheMapValue(SystemConstants.REDIS_VIEWCOUNT_KEY,id.toString(),1);
        return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult add(AddArticleDto articleDto) {
        //添加 博客
        Article article = BeanCopyUtils.copyBean(articleDto, Article.class);
        save(article);


        List<ArticleTag> articleTags = articleDto.getTags().stream()
                .map(tagId -> new ArticleTag(article.getId(), tagId))
                .collect(Collectors.toList());

        //添加 博客和标签的关联
        articleTagService.saveBatch(articleTags);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getlistPage(Integer pageNum, Integer pageSize, String title, String summary) {
        // 模糊查询
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(title),Article::getTitle,title);
        queryWrapper.like(StringUtils.hasText(summary),Article::getSummary,summary);
        queryWrapper.eq(Article::getStatus,SystemConstants.STATUS_NORMAL);

        // 分页
        Page<Article> pageInfo = new Page<>(pageNum,pageSize);
        page(pageInfo,queryWrapper);

        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(pageInfo.getRecords(), ArticleListVo.class);

        // 封装数据
        PageVo pageVo = new PageVo(articleListVos,pageInfo.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getArticleInfo(Long id) {
        // 查询文章
        Article article = articleMapper.selectById(id);

        // 查询出绑定的标签
        LambdaQueryWrapper<ArticleTag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ArticleTag::getArticleId,id);

        List<ArticleTag> articleTags = articleTagService.list(queryWrapper);

        // 数据封装
        List<Long> tags = new ArrayList<>();
        for (ArticleTag tag : articleTags) {
            tags.add(tag.getTagId());
        }

        ArticleInfoVo articleInfoVo = BeanCopyUtils.copyBean(article, ArticleInfoVo.class);
        articleInfoVo.setTags(tags);

        return ResponseResult.okResult(articleInfoVo);
    }

    @Override
    @Transactional
    public ResponseResult updateArticle(UpdateArticleDto updateArticleDto) {
        // 修改文章
        Article article = BeanCopyUtils.copyBean(updateArticleDto, Article.class);
        articleMapper.updateById(article);

        // 修改标签,先全部删除,在添加
        articleTagService.removeByIds(updateArticleDto.getTags());

        List<ArticleTag> articleTags = updateArticleDto.getTags().stream()
                .map(tagId -> new ArticleTag(updateArticleDto.getId(), tagId))
                .collect(Collectors.toList());

        //添加 博客和标签的关联
        articleTagService.saveBatch(articleTags);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult removeArticle(Long id) {
        // 进行伪删除
        LambdaUpdateWrapper<Article> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Article::getDelFlag,SystemConstants.DelFlagNO);
        updateWrapper.eq(Article::getId,id);

        super.update(updateWrapper);

        return ResponseResult.okResult();
    }

}




